<template >
  <div id="user_info_div">
    <div class="user-info-wrap">
      <div class="user-info-box">
        <div class="user-title" @click="closeUserInfoBox">
          <span class="V7_iconfont V7_iconV7tubiao_mianfanhui"></span>基本信息
        </div>
        <el-form class="m7-form user-form" :model="userForm" :rules="rules1" label-position="top" ref="userForm" label-width="90px" size="mini">
          <div class="clearfix">
            <div class="fl">
              <el-form-item label="座席姓名" prop="agentName" style="width:320px;">
                <el-input size="mini" type="text" v-model.trim="userForm.agentName" auto-complete="off"></el-input>
              </el-form-item>
              <el-form-item label="手机号码" prop="mobile" style="width:320px;">
                <el-input  size="mini" type="text" v-model.trim="userForm.mobile" auto-complete="off"></el-input>
              </el-form-item>
            </div>
            <el-form-item class="fl" style="margin-left:30px;">
              <span slot="label">
                头像
                <el-tooltip class="item" effect="dark" content="仅支持JPG、GIF、PNG、BMP图片文件，且文件小于3M" placement="top">
                  <span class="V7_iconfont V7_iconV7tubiao_bangzhu-42 tip-span"></span>
                </el-tooltip>
              </span>
              <img class="agent-img" v-if="userImage" :src="userImage" alt="">
              <img class="agent-img" src='../../assets/img/userAgent.png' v-else alt="">
              <el-upload
                      :show-file-list="false"
                      accept=".jpg, .gif, .png, .bmp"
                      action=""
                      :on-success="uploadSuccess"
                      :on-error="uploadError"
                      :before-upload="beforeUpload"
                      :http-request="uploadRequest">
                <el-button size="small" class="V7_iconfont V7_iconV7tubiao_shangchuan-97 normal-btn">上传头像</el-button>
              </el-upload>
            </el-form-item>
          </div>
          <el-form-item label="座席邮箱" prop="email" style="width:320px;">
            <el-input size="mini" type="text" v-model.trim="userForm.email" auto-complete="off"></el-input>
          </el-form-item>
          <el-form-item label="密码" style="margin-top: 40px;">
            <el-button size="small" class="V7_iconfont V7_iconV7tubiao_mima normal-btn" @click="changeUserPassword">更改密码</el-button>
          </el-form-item>
          <el-form-item v-if="userLimit" label="手动外呼支持自动跳转" style="margin-top: 40px;">
            <el-radio v-model="userForm.autoOutCall" :label="true">是</el-radio>
            <el-radio v-model="userForm.autoOutCall" :label="false">否</el-radio>
          </el-form-item>
          <el-form-item style="margin-top: 40px;">
            <el-button size="mini" type="primary" @click="saveUserInfo">保存</el-button>
          </el-form-item>
        </el-form>
      </div>
    </div>
    <el-dialog title="更改密码" :visible.sync="showPasswordDialog" :append-to-body="true" width="480px" :destroy-on-close="true" :close-on-click-modal="false">
      <el-form class="m7-form" :model="passwordForm" :rules="rules2"  ref="passwordForm" label-position="top" label-width="90px" size="mini">
        <el-form-item label="旧密码" prop="oldPassword">
          <el-input size="mini" :type="passwordControl.oldPass.passwordType" v-model="passwordForm.oldPassword" placeholder="请输入原密码" auto-complete="off">
            <i slot="suffix" class="V7_iconfont V7_iconV7tubiao_bukejian pass-icon" v-show="passwordControl.oldPass.passwordType === 'password'" @click="passwordShowFun('text', 'oldPass')"></i>
            <i slot="suffix" class="V7_iconfont V7_iconV7tubiao_kejian pass-icon" v-show="passwordControl.oldPass.passwordType === 'text'" @click="passwordShowFun('password', 'oldPass')"></i>
          </el-input>
        </el-form-item>
        <el-form-item label="新密码" prop="pass">
          <el-input size="mini" :type="passwordControl.currentPass.passwordType" v-model="passwordForm.pass" placeholder="请输入新密码" auto-complete="off">
            <i slot="suffix" class="V7_iconfont V7_iconV7tubiao_bukejian pass-icon" v-show="passwordControl.currentPass.passwordType === 'password'" @click="passwordShowFun('text', 'currentPass')"></i>
            <i slot="suffix" class="V7_iconfont V7_iconV7tubiao_kejian pass-icon" v-show="passwordControl.currentPass.passwordType === 'text'" @click="passwordShowFun('password', 'currentPass')"></i>
          </el-input>
        </el-form-item>
        <el-form-item label="确认新密码" prop="password">
          <el-input size="mini" :type="passwordControl.newPass.passwordType" v-model="passwordForm.password" placeholder="请再次输入新密码" auto-complete="off">
            <i slot="suffix" class="V7_iconfont V7_iconV7tubiao_bukejian pass-icon" v-show="passwordControl.newPass.passwordType === 'password'" @click="passwordShowFun('text', 'newPass')"></i>
            <i slot="suffix" class="V7_iconfont V7_iconV7tubiao_kejian pass-icon" v-show="passwordControl.newPass.passwordType === 'text'" @click="passwordShowFun('password', 'newPass')"></i>
          </el-input>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="showPasswordDialog = false" size="mini">取消</el-button>
        <el-button type="primary" @click="savePassword" size="mini">保存</el-button>
      </div>
    </el-dialog>
  </div>
</template>
<script lang="ts">
import Vue from 'vue'
import { isNumber2, isEmail } from '@/utils/validate'
import { regexPass, deepClone } from '@/utils/common'
import { organizationConfigModule } from '@/store/modules/config/organizationConfig/index'
import { Component } from 'vue-property-decorator'
import { CommonModule } from '@/store/modules/common'
import { uploadQiniu } from '@/utils/upload'
import { checkPermission } from '@/utils/directive'
import { Base64 } from 'js-base64'
import NodeRSA from 'node-rsa'
interface UserObj {
  agentName: string
  mobile: string
  email: string
  userIcon: string,
  autoOutCall: boolean
}
interface PasswordObj {
  pass: string
  password: string
  oldPassword: string
}
@Component({
  name: 'userInfo'
})
export default class UserInfo extends Vue {
  private $message: any
  private $store: any
  private userLimit: boolean = false
  private showPasswordDialog: boolean = false // 设置密码弹窗控制值
  private passwordControl: object = { // 密码表单的小眼睛控制
    oldPass: { passwordType: 'password' },
    currentPass: { passwordType: 'password' },
    newPass: { passwordType: 'password' }
  }

  private userImage: string = '' // 座席头像
  private userForm: UserObj = { // 个人基本信息
    agentName: '',
    mobile: '',
    email: '',
    userIcon: '',
    autoOutCall: false
  }

  private fileName = '' // 本地文件名称

  private passwordForm: PasswordObj = { // 密码信息表单
    pass: '',
    password: '',
    oldPassword: ''
  }

  private validateMobile = (rule, value, callback) => { // 验证手机号是数字
    if ((CommonModule as any).session.user.postSaleCloudVersion === 1 && value === '') {
      callback(new Error('请输入手机号码'))
    }
    if (value !== '') {
      if (!isNumber2(value)) {
        callback(new Error('请输入正确的数字'))
      } else {
        callback()
      }
    } else {
      callback()
    }
  }

  private validateEmail = (rule, value, callback) => { // 验证邮箱规则
    if (value !== '') {
      if (!isEmail(value)) {
        callback(new Error('请输入正确的邮箱'))
      } else {
        callback()
      }
    } else {
      callback()
    }
  }

  private validateOldPass = (rule, value, callback) => { // 旧密码必填
    if (value === '') {
      callback(new Error('请输入密码'))
    } else {
      callback()
    }
  }

  private validatePass = (rule, value, callback) => { // 输入的新密码校验
    if (value === '') {
      callback(new Error('请输入密码'))
    } else if (!regexPass(value, this.getFormPass())) {
      callback(new Error('密码必须大于等于8位，并包含数字，小写字母，大写字母，特殊字符中的至少3种，特殊字符不能是%、&、+、\'、\\"、<、>、='))
    } else {
      callback()
    }
  }

  private validatePass2 = (rule, value, callback) => { // 再次确认密码的校验
    if (value === '') {
      callback(new Error('请输入密码'))
    } else if (!regexPass(value, this.getFormPass())) {
      callback(new Error('密码必须大于等于8位，并包含数字，小写字母，大写字母，特殊字符中的至少3种，特殊字符不能是%、&、+、\'、\\"、<、>、='))
    } else if (value !== this.getFormPass()) {
      callback(new Error('密码与新密码不一致'))
    } else {
      callback()
    }
  }

  get isAfterSale () {
    return this.$store.state.common.session.user.postSaleCloudVersion === 1
  }

  private rules1: object = { // 个人信息的校验
    agentName: [{ required: true, message: '必填', trigger: 'blur' }],
    mobile: [{ required: this.isAfterSale, validator: this.validateMobile, trigger: 'blur' }],
    email: [{ validator: this.validateEmail, trigger: 'blur' }]
  }

  private rules2: object = { // 密码弹窗里的校验
    oldPassword: [{ required: true, validator: this.validateOldPass, trigger: 'blur' }],
    pass: [{ required: true, validator: this.validatePass, trigger: 'blur' }],
    password: [{ required: true, validator: this.validatePass2, trigger: 'blur' }]
  }

  private getFormPass () { // validator中直接取form值只能取到初始化的"", 所以需要通过方法转换下
    return this.passwordForm.pass
  }

  private uploadRequest (request: any) { // 七牛上传
    uploadQiniu({ type: 'common', fileName: this.fileName }, request)
  }

  private uploadSuccess (data: any) { // 上传成功
    this.userForm.userIcon = data.key
    const initConfig = this.$store.state.common.initConfig
    this.userImage = initConfig && data.key ? `${initConfig.qiniuDomainMap.common}/${data.key}` : ''
  }

  private uploadError () { // 上传失败
    this.$message({ message: '文件上传失败，请重新选择文件上传', type: 'error' })
  }

  private beforeUpload (file: any) { // 上传前验证文件合法性
    this.fileName = file.name.replace(/\s/g, '')
    if (file.size / 1024 / 1024 > 3) {
      this.$message({ message: '头像大小不能超过3M', type: 'error' })
      return false
    }
  }

  private saveUserInfo () { // 保存个人信息
    (this as any).$refs.userForm.validate((valid) => {
      if (valid) {
        const actionData = { url: '/base/action/user/update/information', method: 'POST', data: this.userForm }
        organizationConfigModule.organizationCommonAction(actionData).then(res => {
          if (res && res.success) {
            this.$message({ message: '修改成功', type: 'success' })
            CommonModule.setUserInfo(this.userForm)
          }
        })
      } else {
        return false
      }
    })
  }

  private rsaPassword (password) { // res加密密码
    const pk = Base64.decode(this.$store.state.common.preLogin.pk)
    const key = new NodeRSA(pk)
    return key.encrypt(password, 'base64')
  }

  private changeUserPassword () { // 每次打开修改密码弹窗，重置表单信息
    this.passwordForm = { pass: '', password: '', oldPassword: '' }
    this.showPasswordDialog = true
  }

  private savePassword () { // 保存密码
    (this as any).$refs.passwordForm.validate((valid) => {
      if (valid) {
        const cloneFrom = deepClone(this.passwordForm)
        const oldPassword = this.rsaPassword(cloneFrom.oldPassword) || ''
        const password = this.rsaPassword(cloneFrom.password) || ''
        const actionData = { url: '/base/action/user/update/information', method: 'POST', data: { oldPassword, password } }
        organizationConfigModule.organizationCommonAction(actionData).then(res => {
          if (res && res.success) {
            this.showPasswordDialog = false
            this.$message({ message: '修改密码成功', type: 'success' })
          }
        })
      } else {
        return false
      }
    })
  }

  private closeUserInfoBox () { // 隐藏个人信息页面
    const pane = document.getElementById('user_info_div')
    if (pane) {
      pane.style.display = 'none'
    }
  }

  private passwordShowFun (type: string, pass) { // 密码是否可见切换事件
    this.passwordControl[pass].passwordType = type
  }

  private beforeMount () {
    const user = this.$store.state.common.session.user
    this.userForm.agentName = user ? user.agentName : '--'
    this.userForm.mobile = user ? user.mobile : '--'
    this.userForm.email = user ? user.email : '--'
    this.userForm.autoOutCall = user ? user.autoOutCall : false
    this.userForm.userIcon = user ? user.userIcon : '--'
    const initConfig = this.$store.state.common.initConfig
    this.userImage = initConfig && this.userForm.userIcon ? `${initConfig.qiniuDomainMap.common}/${this.userForm.userIcon}` : ''
    if (checkPermission(null, { value: ['manual_dialout_automatic_jump'] }, 'limits')) {
      this.userLimit = true
    }
  }
}
</script>
<style scoped lang="stylus">
  .navMenuState #user_info_div
    width calc(100vw - 130px)
    left 126px
  .pass-icon
    padding-right 6px
  #user_info_div
    display none
    background #fff
    position fixed
    left 74px
    top 58px
    border-radius 18px
    width calc(100vw - 74px)
    height calc(100vh - 56px)
    padding 16px
    z-index 1002
    .user-info-wrap
      box-shadow 0px 0px 3px 0px #E0E5F0, 0px 1px 4px 0px #E0E5F0
      border-radius 10px
      height 100%
      overflow auto
    .user-info-box
      font-size 12px
      .user-title
        color $fc-gray
        font-size 14px
        line-height 14px
        font-weight bold
        padding 21px 24px
        cursor pointer
        width 100%
        height 56px
        box-shadow 0px 1px 4px 0px #E0E6F0
        border-radius 10px 10px 0px 0px
        .V7_iconfont
          color #B3B9C7
          margin-right 8px
          font-size 14px
      .user-form
        padding 24px
      .agent-img
        border-radius 50%
        display block
        width 70px
        height 70px
        margin 0 auto
        margin-bottom 10px
      .agent-img.V7_iconfont
        font-size 70px
        color $icon-gray
        line-height 70px
        margin-left 15px
      .normal-btn
        font-size 12px
        &:before
          padding-right 4px
          color $icon-gray
        &:hover:before
          color #008CEE
      .tip-span
        color #B3B9C7
        font-size 12px
        cursor pointer
</style>
